package com.yayhos.parallaxrecyclerview;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Image;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Matrix;
import ohos.agp.utils.Point;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import java.math.BigDecimal;
import java.util.Optional;

/**
 * Created by yahyabayramoglu on 15/04/15.
 */
public class ParallaxImageView extends Image {


    private static final float DEFAULT_PARALLAX_RATIO = 1.5f;
    private float parallaxRatio = DEFAULT_PARALLAX_RATIO;
    private ParallaxImageListener listener;

    private int rowYPos = -1;
    private int recyclerViewHeight = -1;
    private int recyclerViewYPos = -1;
    private Context context;
    private int index = -1;
    private PixelMap myPixelMap;

    public PixelMap getMyPixelMap() {
        return myPixelMap;
    }

    public void setMyPixelMap(PixelMap myPixelMap) {
        this.myPixelMap = myPixelMap;
    }

    public interface ParallaxImageListener {
        int[] requireValuesForTranslate();
    }

    public ParallaxImageView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public ParallaxImageView(Context context, AttrSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public ParallaxImageView(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    private void init() {

        if (getScreenWidth(context) < getScreenHeight(context)) {
            imageMatrix.setScale(recomputeImageMatrix(), recomputeImageMatrix());

            this.addDrawTask((component, canvas) -> {
                canvas.save();
                canvas.concat(imageMatrix);
                if (index == -1) {
                    canvas.drawPixelMapHolder(new PixelMapHolder(getMyPixelMap()), 0, -330, new Paint());
                } else {
                    canvas.drawPixelMapHolder(new PixelMapHolder(getMyPixelMap()), 0, -200, new Paint());

                }

                canvas.restore();
            });
        } else {
            imageMatrix.setScale(recomputeImageMatrix(), recomputeImageMatrix());

            this.addDrawTask((component, canvas) -> {
                canvas.save();
                canvas.concat(imageMatrix);
                if (index == -1) {
                    canvas.drawPixelMapHolder(new PixelMapHolder(getMyPixelMap()), 0, -270, new Paint());

                } else {
                    canvas.drawPixelMapHolder(new PixelMapHolder(getMyPixelMap()), 0, -200, new Paint());
                }
                canvas.restore();
            });
        }

    }


    public void setListener(ParallaxImageListener listener) {
        this.listener = listener;
    }

    public ParallaxImageListener getListener() {
        return listener;
    }

    public synchronized boolean doTranslate() {
        if (getListener() != null && getValues()) {
            calculateAndMove();
            return true;
        } else {
            return false;
        }
    }

    private boolean getValues() {
        int[] values = getListener().requireValuesForTranslate();
        if (values == null){
            return false;
        }
        this.rowYPos = values[0];
        this.recyclerViewHeight = getScreenHeight(context);
        this.recyclerViewYPos = 70;
        return true;
    }

    private void calculateAndMove() {
        float distanceFromCenter = (recyclerViewYPos + recyclerViewHeight) / 2 - rowYPos;
        float difference = 1269f;
        float move = (distanceFromCenter / recyclerViewHeight) * difference * parallaxRatio;
        moveTo((new BigDecimal(move).divide(new BigDecimal(2)) ).subtract (new BigDecimal(difference).divide(new BigDecimal(2)) ).floatValue(), recomputeImageMatrix());
    }

    private float recomputeImageMatrix() {
        float Width = getScreenWidth(context);

        BigDecimal num1= new BigDecimal(Width);
        BigDecimal num2=num1.divide(new BigDecimal(100));
        BigDecimal  num3=num2.multiply(new BigDecimal(0.12f));
        return num3.floatValue();
    }

    Matrix imageMatrix = new Matrix();

    private void moveTo(float move, float scale) {
        imageMatrix = new Matrix();
        imageMatrix.setScale(scale, scale);
        imageMatrix.postTranslate(0, move);
        index = 0;
        invalidate();
    }

    private int getScreenHeight(Context context) {
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(context);
        Point size = new Point();
        display.get().getSize(size);
        return (int) size.getPointY();
    }

    private float getScreenWidth(Context context) {
        Optional<Display> display = DisplayManager.getInstance().getDefaultDisplay(context);
        Point size = new Point();
        display.get().getSize(size);
        return size.getPointX();
    }
}